package com.suray.wcs.service.resmap;

import com.suray.basic.wcs.utils.Crc16;
import com.suray.wcs.res.msgparse.ByteBeanUtil;
import com.suray.wcs.res.msgparse.HeartSendBean;
import com.suray.wcs.res.msgparse.MapDataResult;
import com.suray.wcs.res.service.rescontact.MapDataModel;
import com.suray.wcs.service.core.util.LongConnSendUtilLora;
import com.suray.wcs.service.pojo.Rgv;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 * @author Shaozn
 */
public class MapMessageSend {
    /**
     * 开始标识
     */
    private final static byte SOH = 0x01;
    /**
     * 结束标识
     */
    private final static byte EOT = 0x04;
    /**
     * 应答标识
     */
    private final static byte ACK = 0x06;
    /**
     * 重传标识
     */
    private final static byte NAK = 0x15;
    /**
     * 无条件结束标识
     */
    private final static byte CAN = 0x18;
    /**
     * 以1024字节块的形式传输数据
     */
    private final static int SECTOR_SIZE = 128;
    /**
     * 最大错误（无应答）包数
     */
    private final static int MAX_ERRORS = 10;
    /**
     * 不足的补0x1A
     */
    protected static final byte CPMEOF = (byte) 0x1a;

    public MapMessageSend() {
    }


    /**
     * @param filePath 文件路径
     * @param rgv      小车
     */
    public static synchronized void packData(String filePath, Rgv rgv) throws IOException {
        byte[] block = new byte[SECTOR_SIZE];
        // 读取文件初始化
        DataInputStream inputStream = new DataInputStream(new FileInputStream(filePath));
        int blockNumber = 0;
        while (inputStream.read(block) != -1) {
            MapDataResult mapDataResult = sendData(block, blockNumber, rgv, SOH);
            if(!mapDataResult.getDataBack().equals((int) ACK)){
                sendData(block, blockNumber + 1, rgv, EOT);
                throw  new IOException("发送返回结果错误"+mapDataResult.getDataBack());
            }
            blockNumber = blockNumber+1;
            //序号1 - 255循环
            if (blockNumber == 256) {
                blockNumber = 1;
            }
        }
        // 所有数据发送完成后，发送结束标识
        sendData(block, blockNumber, rgv, EOT);
        rgv.getRgvHeart().setMode(HeartSendBean.Mode.ONE.getCode());
    }

    /**
     * 发送结束标志
     *
     * @param block
     * @param blockNumber
     * @param rgv
     * @return
     * @throws IOException
     */
    private static MapDataResult sendData(byte[] block, int blockNumber, Rgv rgv, byte sign) throws IOException {
        YmodelData ymd = new YmodelData();
        ymd.setSign(sign);
        ymd.setOrder(blockNumber);
        ymd.setComplement((byte) ~blockNumber);
        ymd.setData(block);
        int checkSum = Crc16.CRC_XModem(ymd.getData(), ymd.getData().length) & 0x00ffff;
        ymd.setXor1((byte) checkSum);
        ymd.setXor2((byte) ((checkSum >> 8) & 0xff));
        MapDataModel mapDataModel = new MapDataModel();
        mapDataModel.setData(putChar(ymd));
        mapDataModel.setDeviceNo(rgv.getRgvDB().getRgvNo());
        mapDataModel.setMode(HeartSendBean.Mode.THREE.getCode());
        byte[] mapByte = ByteBeanUtil.toByte(mapDataModel, rgv.getRgvDB().getRgvNo());
        return ByteBeanUtil.parseByteMap(LongConnSendUtilLora.send(mapByte,rgv));
    }

    /**
     * 发送数据
     *
     * @param ymd
     * @return
     * @throws IOException
     */
    private static byte[] putChar(YmodelData ymd) {
        ByteBuffer bb = ByteBuffer.allocate(ymd.getData().length + 5).order(
                ByteOrder.BIG_ENDIAN);
        bb.put(ymd.getSign());
        bb.put((byte) ymd.getOrder());
        bb.put((byte) ymd.getComplement());
        bb.put(ymd.getData());
        bb.put(ymd.getXor2());
        bb.put(ymd.getXor1());
        return bb.array();
    }

}
